package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.bean.BeanValidators;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.mapper.CapitalAccountMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.QwhBankJournalMapper;
import com.ruoyi.system.domain.QwhBankJournal;
import com.ruoyi.system.service.IQwhBankJournalService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 银行日记账Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-02-25
 */
@Service
@Transactional
public class QwhBankJournalServiceImpl implements IQwhBankJournalService 
{
    @Autowired
    private QwhBankJournalMapper qwhBankJournalMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CapitalAccountMapper capitalAccountMapper;

    /**
     * 查询银行日记账
     * 
     * @param id 银行日记账主键
     * @return 银行日记账
     */
    @Override
    public QwhBankJournal selectQwhBankJournalById(Long id)
    {
        return qwhBankJournalMapper.selectQwhBankJournalById(id);
    }

    /**
     * 查询银行日记账列表
     * 
     * @param qwhBankJournal 银行日记账
     * @return 银行日记账
     */
    @Override
    public List<QwhBankJournal> selectQwhBankJournalList(QwhBankJournal qwhBankJournal)
    {
        return qwhBankJournalMapper.selectQwhBankJournalList(qwhBankJournal);
    }

    /**
     * 新增银行日记账
     * 
     * @param qwhBankJournal 银行日记账
     * @return 结果
     */
    @Override
    public int insertQwhBankJournal(QwhBankJournal qwhBankJournal)
    {
        // 获取当前银行的最新余额
        BigDecimal latestBalance = qwhBankJournalMapper.findLatestBalanceByBankName(qwhBankJournal.getBankId())
                .orElse(BigDecimal.ZERO); // 如果没有记录，默认余额为0

        // 计算新的余额
        BigDecimal newBalance = latestBalance;
        if (qwhBankJournal.getIncome() != null) {
            newBalance = newBalance.add(qwhBankJournal.getIncome()); // 收入增加余额
        } else if (qwhBankJournal.getDisburse() != null) {
            newBalance = newBalance.subtract(qwhBankJournal.getDisburse()); // 支出减少余额
        }
        qwhBankJournal.setBalance(newBalance);
qwhBankJournal.validate();
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 定义时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        // 格式化时间戳
        qwhBankJournal.setTradingStatement(now.format(formatter));


//获取当前登录人id
        Long userId = SecurityUtils.getUserId();
//获取银行编码
//当天日期
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyyyMMdd");
        String date = currentDate.format(formatters);





        return qwhBankJournalMapper.insertQwhBankJournal(qwhBankJournal);
    }

    /**
     * 修改银行日记账
     * 垃圾功能有待完善
     * @param qwhBankJournal 银行日记账
     * @return 结果
     */
    @Override
    public int updateQwhBankJournal(QwhBankJournal qwhBankJournal)
    {
        // 重新计算当前记录的余额
        BigDecimal previousBalance = getPreviousBalance(qwhBankJournal);
        BigDecimal newBalance = previousBalance;
        if (qwhBankJournal.getIncome() != null) {
            newBalance = newBalance.add(qwhBankJournal.getIncome());
        } else if (qwhBankJournal.getDisburse() != null) {
            newBalance = newBalance.subtract(qwhBankJournal.getDisburse());
        }
        qwhBankJournal.setBalance(newBalance);

        // 更新当前记录
        qwhBankJournalMapper.updateQwhBankJournal(qwhBankJournal);

        // 重新计算后续记录的余额
        updateSubsequentBalances(qwhBankJournal);



        return qwhBankJournalMapper.updateQwhBankJournal(qwhBankJournal);
    }


    // 获取当前记录的前一条记录的余额
    private BigDecimal getPreviousBalance(QwhBankJournal journal) {
        return qwhBankJournalMapper.findPreviousBalance(journal.getBankId(), journal.getTradingStatement(), journal.getId())
                .orElse(BigDecimal.ZERO);
    }

    // 更新后续记录的余额
    private void updateSubsequentBalances(QwhBankJournal journal) {
        List<QwhBankJournal> subsequentJournals = qwhBankJournalMapper.findSubsequentJournals(journal.getBankId(), journal.getTradingStatement(), journal.getId());

        // 使用 AtomicReference 保存当前余额
        AtomicReference<BigDecimal> currentBalance = new AtomicReference<>(journal.getBalance());


//        for (QwhBankJournal subsequentJournal : subsequentJournals) {
//            if (subsequentJournal.getIncome() != null) {
//                currentBalance = currentBalance.add(subsequentJournal.getIncome());
//            } else if (subsequentJournal.getDisburse() != null) {
//                currentBalance = currentBalance.subtract(subsequentJournal.getDisburse());
//            }
//            subsequentJournal.setBalance(currentBalance);
//            qwhBankJournalMapper.updateQwhBankJournal(subsequentJournal);
//        }

        subsequentJournals.stream().forEach(subsequentJournal -> {
            if (subsequentJournal.getIncome() != null) {
                currentBalance.updateAndGet(balance -> balance.add(subsequentJournal.getIncome())); // 收入增加余额
            } else if (subsequentJournal.getDisburse() != null) {
                currentBalance.updateAndGet(balance -> balance.subtract(subsequentJournal.getDisburse())); // 支出减少余额
            }

            subsequentJournal.setBalance(currentBalance.get());// 批量更新余额
           qwhBankJournalMapper.updateQwhBankJournal(subsequentJournal);
        });


    }

    /**
     * 批量删除银行日记账
     * 
     * @param ids 需要删除的银行日记账主键
     * @return 结果
     */
    @Override
    public int deleteQwhBankJournalByIds(Long[] ids)
    {
        return qwhBankJournalMapper.deleteQwhBankJournalByIds(ids);
    }

    /**
     * 删除银行日记账信息
     * 
     * @param id 银行日记账主键
     * @return 结果
     */
    @Override
    public int deleteQwhBankJournalById(Long id)
    {
        return qwhBankJournalMapper.deleteQwhBankJournalById(id);
    }


    @Override
    public String importUser(List<QwhBankJournal> qwhBankJournals, boolean updateSupport, String operName) {
        if (CollectionUtils.isEmpty(qwhBankJournals)) {
            throw new ServiceException("导入数据为空！");
        }

        int successCount = 0; // 成功导入的记录数
        int failureCount = 0; // 导入失败的记录数
        StringBuilder successMsg = new StringBuilder(); // 成功消息
        StringBuilder failureMsg = new StringBuilder(); // 失败消息

        // 遍历导入的数据
        for (QwhBankJournal journal : qwhBankJournals) {
            try {
                // 检查数据是否已存在
                QwhBankJournal existingJournal = qwhBankJournalMapper.selectJournalByUniqueKey(journal.getTradingStatement());
                if (existingJournal != null) {
                    if (updateSupport) {
                        // 更新支持，更新现有数据
                        journal.setUpdateBy(operName);
                        journal.setUpdateTime(new Date());
                        Object bank = redisTemplate.opsForValue().get("bank");
                        journal.setBankId(Long.parseLong(bank.toString()));
                        qwhBankJournalMapper.updateQwhBankJournal(journal);
                        successCount++;
                        successMsg.append("<br/>").append("更新成功：").append(journal.getTradingStatement());
                    } else {
                        // 更新不支持，跳过
                        failureCount++;
                        failureMsg.append("<br/>").append("跳过已存在记录：").append(journal.getTradingStatement());
                    }
                } else {
                    // 插入新数据
                    journal.setCreateBy(operName);
                    journal.setCreateTime(new Date());
                    Object bank = redisTemplate.opsForValue().get("bank");
                    journal.setBankId(Long.parseLong(bank.toString()));
                    qwhBankJournalMapper.insertQwhBankJournal(journal);
                    successCount++;
                    successMsg.append("<br/>").append("插入成功：").append(journal.getTradingStatement());
                }
            } catch (Exception e) {
                failureCount++;
                failureMsg.append("<br/>").append("导入失败：").append(journal.getTradingStatement()).append("，错误：").append(e.getMessage());
            }
        }

        // 返回导入结果
        if (failureCount > 0) {
            failureMsg.insert(0, "导入失败 " + failureCount + " 条记录：" + successMsg.toString());
            throw new ServiceException(failureMsg.toString());
        } else {
            return "导入成功 " + successCount + " 条记录：" + successMsg.toString();
        }
    }
}
